From 489921e3044f50bae650fe393ef52efc6827a966 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 18 Jun 2007 13:50:42 -0600 Subject: [PATCH] [IA64] Introduce machine vector for platform specific fixups for dom0. This is required to map SN2 specific registers to dom0. Signed-off-by: Jes Sorensen --- xen/arch/ia64/xen/Makefile | 1 + xen/arch/ia64/xen/dom_fw_sn2.c | 92 +++++++++++++++++++ xen/arch/ia64/xen/dom_fw_utils.c | 7 ++ xen/include/asm-ia64/linux-xen/asm/machvec.h | 67 ++++++++++++++ .../asm-ia64/linux-xen/asm/machvec_sn2.h | 7 ++ 5 files changed, 174 insertions(+) create mode 100644 xen/arch/ia64/xen/dom_fw_sn2.c diff --git a/xen/arch/ia64/xen/Makefile b/xen/arch/ia64/xen/Makefile index a0966e2a27..f1e748816a 100644 --- a/xen/arch/ia64/xen/Makefile +++ b/xen/arch/ia64/xen/Makefile @@ -10,6 +10,7 @@ obj-y += dom_fw_common.o obj-y += dom_fw_dom0.o obj-y += dom_fw_domu.o obj-y += dom_fw_utils.o +obj-y += dom_fw_sn2.o obj-y += fw_emul.o obj-y += hpsimserial.o obj-y += hypercall.o diff --git a/xen/arch/ia64/xen/dom_fw_sn2.c b/xen/arch/ia64/xen/dom_fw_sn2.c new file mode 100644 index 0000000000..93da9b6a22 --- /dev/null +++ b/xen/arch/ia64/xen/dom_fw_sn2.c @@ -0,0 +1,92 @@ +/* + * Xen domain0 platform firmware fixups for sn2 + * Copyright (C) 2007 Silicon Graphics Inc. + * Jes Sorensen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#define SWAP_NASID(n, x) ((x & ~NASID_MASK) | NASID_SPACE(n)) + +int __init +sn2_dom_fw_init(domain_t *d, + struct xen_ia64_boot_param *bp, + struct fw_tables *tables) +{ + int node; + short nasid; + unsigned long shubid, shubpicam, shubpiowrite; + + printk("SN2 mapping specific registers to dom0\n"); + + assign_domain_mach_page(d, LOCAL_MMR_OFFSET | SH_RTC, PAGE_SIZE, + ASSIGN_nocache); + + if (is_shub1()) { + /* 0x110060000 */ + shubid = SH1_GLOBAL_MMR_OFFSET + (SH1_SHUB_ID & PAGE_MASK); + /* 0x120050000 */ + shubpicam = SH1_GLOBAL_MMR_OFFSET + + (SH1_PI_CAM_CONTROL & PAGE_MASK); + /* 0x120070000 */ + shubpiowrite = SH1_GLOBAL_MMR_OFFSET + + (SH1_PIO_WRITE_STATUS_0 & PAGE_MASK); + + for_each_online_node(node) { + nasid = cnodeid_to_nasid(node); + shubid = SWAP_NASID(nasid, shubid); + shubpicam = SWAP_NASID(nasid, shubpicam); + shubpiowrite = SWAP_NASID(nasid, shubpiowrite); + + assign_domain_mach_page(d, shubid, PAGE_SIZE, + ASSIGN_nocache); + assign_domain_mach_page(d, shubpicam, PAGE_SIZE, + ASSIGN_nocache); + assign_domain_mach_page(d, shubpiowrite, PAGE_SIZE, + ASSIGN_nocache); + } + + /* map leds */ + assign_domain_mach_page(d, LOCAL_MMR_OFFSET | + SH1_REAL_JUNK_BUS_LED0, + PAGE_SIZE, ASSIGN_nocache); + assign_domain_mach_page(d, LOCAL_MMR_OFFSET | + SH1_REAL_JUNK_BUS_LED1, + PAGE_SIZE, ASSIGN_nocache); + assign_domain_mach_page(d, LOCAL_MMR_OFFSET | + SH1_REAL_JUNK_BUS_LED2, + PAGE_SIZE, ASSIGN_nocache); + assign_domain_mach_page(d, LOCAL_MMR_OFFSET | + SH1_REAL_JUNK_BUS_LED3, + PAGE_SIZE, ASSIGN_nocache); + } else + panic("Unable to build EFI entry for SHUB 2 MMR\n"); + + return 0; +} diff --git a/xen/arch/ia64/xen/dom_fw_utils.c b/xen/arch/ia64/xen/dom_fw_utils.c index 1369b05560..941bacae6a 100644 --- a/xen/arch/ia64/xen/dom_fw_utils.c +++ b/xen/arch/ia64/xen/dom_fw_utils.c @@ -292,6 +292,13 @@ int dom_fw_setup(domain_t * d, unsigned long bp_mpa, unsigned long maxmem) xfree(fw_tables); return ret; } + + ret = platform_fw_init(d, bp, fw_tables); + if (ret < 0) { + xfree(fw_tables); + return ret; + } + if (sizeof(*fw_tables) + fw_tables->num_mds * sizeof(fw_tables->efi_memmap[0]) > fw_tables_size) { diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec.h b/xen/include/asm-ia64/linux-xen/asm/machvec.h index fd1f883b63..56a3d25ebe 100644 --- a/xen/include/asm-ia64/linux-xen/asm/machvec.h +++ b/xen/include/asm-ia64/linux-xen/asm/machvec.h @@ -191,6 +191,15 @@ machvec_noop_pci_legacy_write (struct pci_bus *bus, u16 port, u32 val, u8 size) panic("%s() called", __FUNCTION__); return 0; } + +typedef int ia64_mv_fw_init_t (void *d, void *bp, void *tables); + +static inline int +machvec_noop_platform_fw_init (void *d, void *bp, void *tables) +{ + return 0; +} + #endif extern void machvec_setup (char **); @@ -254,6 +263,9 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); # define platform_readw_relaxed ia64_mv.readw_relaxed # define platform_readl_relaxed ia64_mv.readl_relaxed # define platform_readq_relaxed ia64_mv.readq_relaxed +#ifdef XEN +# define platform_fw_init ia64_mv.fw_init +#endif # endif /* __attribute__((__aligned__(16))) is required to make size of the @@ -302,8 +314,12 @@ struct ia64_machine_vector { ia64_mv_readw_relaxed_t *readw_relaxed; ia64_mv_readl_relaxed_t *readl_relaxed; ia64_mv_readq_relaxed_t *readq_relaxed; +#ifdef XEN + ia64_mv_fw_init_t *fw_init; +#endif } __attribute__((__aligned__(16))); /* align attrib? see above comment */ +#ifdef XEN #define MACHVEC_INIT(name) \ { \ #name, \ @@ -346,7 +362,53 @@ struct ia64_machine_vector { platform_readw_relaxed, \ platform_readl_relaxed, \ platform_readq_relaxed, \ + platform_fw_init, \ } +#else +#define MACHVEC_INIT(name) \ +{ \ + #name, \ + platform_setup, \ + platform_cpu_init, \ + platform_irq_init, \ + platform_send_ipi, \ + platform_timer_interrupt, \ + platform_global_tlb_purge, \ + platform_tlb_migrate_finish, \ + platform_dma_init, \ + platform_dma_alloc_coherent, \ + platform_dma_free_coherent, \ + platform_dma_map_single, \ + platform_dma_unmap_single, \ + platform_dma_map_sg, \ + platform_dma_unmap_sg, \ + platform_dma_sync_single_for_cpu, \ + platform_dma_sync_sg_for_cpu, \ + platform_dma_sync_single_for_device, \ + platform_dma_sync_sg_for_device, \ + platform_dma_mapping_error, \ + platform_dma_supported, \ + platform_local_vector_to_irq, \ + platform_pci_get_legacy_mem, \ + platform_pci_legacy_read, \ + platform_pci_legacy_write, \ + platform_inb, \ + platform_inw, \ + platform_inl, \ + platform_outb, \ + platform_outw, \ + platform_outl, \ + platform_mmiowb, \ + platform_readb, \ + platform_readw, \ + platform_readl, \ + platform_readq, \ + platform_readb_relaxed, \ + platform_readw_relaxed, \ + platform_readl_relaxed, \ + platform_readq_relaxed, \ +} +#endif extern struct ia64_machine_vector ia64_mv; extern void machvec_init (const char *name); @@ -494,5 +556,10 @@ extern ia64_mv_dma_supported swiotlb_dma_supported; #ifndef platform_readq_relaxed # define platform_readq_relaxed __ia64_readq_relaxed #endif +#ifdef XEN +#ifndef platform_fw_init +# define platform_fw_init machvec_noop_platform_fw_init +#endif +#endif #endif /* _ASM_IA64_MACHVEC_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h b/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h index 4af484a7d9..0574a85c3c 100644 --- a/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h +++ b/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h @@ -71,6 +71,9 @@ extern ia64_mv_migrate_t sn_migrate; extern ia64_mv_setup_msi_irq_t sn_setup_msi_irq; extern ia64_mv_teardown_msi_irq_t sn_teardown_msi_irq; #endif +#ifdef XEN +extern ia64_mv_fw_init_t sn2_dom_fw_init; +#endif /* @@ -161,6 +164,10 @@ extern ia64_mv_teardown_msi_irq_t sn_teardown_msi_irq; #endif #endif +#ifdef XEN +#define platform_fw_init sn2_dom_fw_init +#endif + #include #endif /* _ASM_IA64_MACHVEC_SN2_H */ -- 2.30.2